// 信息提示
import { ElMessage } from 'element-plus';

// WebSocket地址
const url = import.meta.env.VITE_GLOB_APP_WEBSOCKET + '/';

// WebSocket实例
let ws: any;

// 重连定时器实例
let reconnectTimer: any;

// 心跳定时器实例
let heartbeatTimer: any;

// 心跳检测定时器实例
let heartbeatCheckTimer: any;

// 连接状态检查定时器
let connectionCheckTimer: any;

// WebSocket重连开关
let isReconnecting = false;

// 心跳配置 - 永久保持连接（优化间隔）
const HEARTBEAT_INTERVAL = 30000; // 30秒发送一次心跳
const HEARTBEAT_TIMEOUT = 10000; // 10秒内没收到心跳回复就认为断开
const RECONNECT_INTERVAL = 30000; // 30秒重连间隔（避免过于频繁）
const CONNECTION_CHECK_INTERVAL = 60000; // 60秒检查一次连接状态

// 当前用户名
let currentUsername = '';

// 心跳状态
let isHeartbeatAlive = true;

// 重连计数器
let reconnectCount = 0;

// 连接保持标志
let shouldKeepAlive = true;

// 心跳相关函数
function startHeartbeat() {
  console.log('WebSocket开始永久心跳检测');
  stopHeartbeat(); // 先清除之前的定时器

  heartbeatTimer = setInterval(() => {
    if (ws && ws.readyState === WebSocket.OPEN && shouldKeepAlive) {
      console.log('WebSocket发送心跳包');
      isHeartbeatAlive = false;
      ws.send('ping');

      // 设置心跳检测超时
      heartbeatCheckTimer = setTimeout(() => {
        if (!isHeartbeatAlive && shouldKeepAlive) {
          console.log('WebSocket心跳超时，准备重连');
          reconnect();
        }
      }, HEARTBEAT_TIMEOUT);
    }
    // 移除连接状态异常的立即重连，避免与连接状态检查冲突
  }, HEARTBEAT_INTERVAL);
}

function stopHeartbeat() {
  if (heartbeatTimer) {
    clearInterval(heartbeatTimer);
    heartbeatTimer = null;
  }
  if (heartbeatCheckTimer) {
    clearTimeout(heartbeatCheckTimer);
    heartbeatCheckTimer = null;
  }
}

function resetHeartbeat() {
  isHeartbeatAlive = true;
  if (heartbeatCheckTimer) {
    clearTimeout(heartbeatCheckTimer);
    heartbeatCheckTimer = null;
  }
}

// 连接状态检查函数（优化版本）
function startConnectionCheck() {
  console.log('WebSocket开始连接状态检查');
  stopConnectionCheck();

  connectionCheckTimer = setInterval(() => {
    if (shouldKeepAlive && currentUsername) {
      const readyState = ws ? ws.readyState : WebSocket.CLOSED;

      // 只在连接异常时才输出日志和处理
      if (readyState === WebSocket.CLOSED) {
        console.log('WebSocket连接状态检查: 连接已断开，启动重连');
        reconnect();
      }
      // 连接正常时不做额外操作，避免与心跳机制冲突
    }
  }, CONNECTION_CHECK_INTERVAL);
}

function stopConnectionCheck() {
  if (connectionCheckTimer) {
    clearInterval(connectionCheckTimer);
    connectionCheckTimer = null;
  }
}

// WebSocket对象
export const websocket = {
  // WebSocket建立连接 - 永久保持
  Init(username: string) {
    const timestamp = new Date().toLocaleTimeString();
    console.log(`[${timestamp}] WebSocket.Init() 被调用，用户名: ${username}`);

    // 判断浏览器是否支持WebSocket
    if (!('WebSocket' in window)) {
      ElMessage.error('您的浏览器不支持 WebSocket');
      return;
    }

    // 启用永久保持连接
    shouldKeepAlive = true;
    isReconnecting = false;

    // 保存当前用户名
    currentUsername = username;

    // 先关闭之前的连接
    if (ws) {
      console.log(`[${timestamp}] 关闭之前的WebSocket连接`);
      ws.close();
    }

    console.log(`[${timestamp}] WebSocket开始连接:`, url + username);

    // 创建WebSocket实例
    ws = new WebSocket(url + username);

    // 监听WebSocket连接
    ws.onopen = () => {
      console.log('WebSocket永久连接建立成功');
      isReconnecting = false;
      // 重置重连计数
      reconnectCount = 0;
      // 连接成功后开始永久心跳和状态检查
      startHeartbeat();
      startConnectionCheck();
    };

    // 监听WebSocket连接关闭
    ws.onclose = (e: any) => {
      console.log('WebSocket连接关闭', e.code, e.reason, '保持连接标志:', shouldKeepAlive);
      stopHeartbeat();
      stopConnectionCheck();
      // 如果需要保持连接且不是主动关闭，则延迟重连
      if (shouldKeepAlive && !isReconnecting) {
        console.log('WebSocket意外断开，准备重连');
        // 使用标准重连间隔，避免过于频繁
        setTimeout(() => reconnect(), RECONNECT_INTERVAL);
      }
    };

    // 监听WebSocket连接错误信息
    ws.onerror = (e: any) => {
      console.log('WebSocket数据传输发生错误', e);
      stopHeartbeat();
      stopConnectionCheck();
      // 打开重连
      if (!isReconnecting && shouldKeepAlive) {
        reconnect();
      }
    };

    // 监听WebSocket接收消息
    ws.onmessage = (e: any) => {
      // console.log('WebSocket接收后端消息:' + e.data);

      // 处理心跳回复
      if (e.data === 'pong' || e.data === 'ok') {
        console.log('WebSocket收到心跳回复');
        resetHeartbeat();
        return;
      }

      // 调用回调函数处理接收到的消息
      if (websocket.onMessageCallback) {
        websocket.onMessageCallback(e.data);
      }
    };
  },

  // WebSocket连接关闭方法
  Close() {
    console.log('WebSocket主动关闭连接，停止永久保持');
    // 停止永久保持连接
    shouldKeepAlive = false;
    // 关闭断开重连机制
    isReconnecting = true;
    // 停止心跳和状态检查
    stopHeartbeat();
    stopConnectionCheck();
    // 清除重连定时器
    if (reconnectTimer) {
      clearTimeout(reconnectTimer);
      reconnectTimer = null;
    }
    // 重置重连计数
    reconnectCount = 0;
    // 关闭连接
    if (ws) {
      ws.close();
    }
  },

  // WebSocket发送信息方法
  Send(data: any) {
    // 处理发送数据JSON字符串
    const msg = JSON.stringify(data);
    // 发送消息给后端
    ws.send(msg);
  },

  // 暴露WebSocket实例，其他地方调用就调用这个
  getWebSocket() {
    return ws;
  },

  // 新增回调函数用于处理收到的消息
  onMessageCallback: null as ((data: any) => void) | null,

  // 设置消息处理回调函数
  setMessageCallback(callback: any) {
    this.onMessageCallback = callback;
  },

  // 检查连接状态
  isConnected() {
    return ws && ws.readyState === WebSocket.OPEN;
  },

  // 获取连接状态
  getReadyState() {
    return ws ? ws.readyState : WebSocket.CLOSED;
  },

  // 手动触发心跳检测
  ping() {
    if (this.isConnected()) {
      console.log('WebSocket手动发送心跳');
      ws.send('ping');
    }
  },

  // 重新连接
  reconnect() {
    if (!isReconnecting && shouldKeepAlive) {
      reconnect();
    }
  },

  // 启用永久保持连接
  enableKeepAlive() {
    console.log('WebSocket启用永久保持连接');
    shouldKeepAlive = true;
    // 如果当前没有连接，尝试连接
    if ((!ws || ws.readyState !== WebSocket.OPEN) && currentUsername) {
      this.Init(currentUsername);
    }
  },

  // 禁用永久保持连接
  disableKeepAlive() {
    console.log('WebSocket禁用永久保持连接');
    shouldKeepAlive = false;
  },

  // 获取连接统计信息
  getConnectionStats() {
    return {
      reconnectCount,
      shouldKeepAlive,
      isReconnecting,
      currentUsername,
      readyState: ws ? ws.readyState : WebSocket.CLOSED
    };
  }
};

// 重连方法 - 优化重连逻辑
function reconnect() {
  const timestamp = new Date().toLocaleTimeString();
  console.log(`[${timestamp}] WebSocket准备重连，当前重连开关:`, isReconnecting, '保持连接标志:', shouldKeepAlive);

  // 判断是否主动关闭连接或不需要保持连接
  if (isReconnecting || !shouldKeepAlive) {
    console.log(`[${timestamp}] WebSocket已主动关闭或不需要保持连接，跳过重连`);
    return;
  }

  // 检查是否已经在重连中
  if (reconnectTimer) {
    console.log(`[${timestamp}] WebSocket重连已在进行中，跳过重复重连`);
    return;
  }

  // 增加重连计数
  reconnectCount++;
  console.log(`[${timestamp}] WebSocket第 ${reconnectCount} 次重连尝试，将在 ${RECONNECT_INTERVAL}ms 后执行`);

  // 设置重连定时器
  reconnectTimer = setTimeout(function () {
    const execTimestamp = new Date().toLocaleTimeString();
    console.log(`[${execTimestamp}] WebSocket执行第 ${reconnectCount} 次断线重连...`);

    // 清除重连定时器
    reconnectTimer = null;

    // 优先使用保存的用户名，否则从localStorage获取
    let username = currentUsername;
    if (!username) {
      username = JSON.parse(localStorage.getItem('msgprofile') || '{}')?.wx_id;
    }

    if (username && shouldKeepAlive) {
      // 设置重连状态，防止重复重连
      isReconnecting = true;
      console.log(`[${execTimestamp}] WebSocket开始重连，用户名: ${username}`);
      websocket.Init(username);
    } else {
      console.error(`[${execTimestamp}] WebSocket重连失败：无法获取用户名`);
      // 减少重连计数，因为这次重连没有实际执行
      reconnectCount--;
    }
  }, RECONNECT_INTERVAL);
}

// 监听窗口关闭事件，当窗口关闭时-每一个页面关闭都会触发-扩张需求业务
window.onbeforeunload = function () {
  // 在窗口关闭时关闭 WebSocket 连接
  websocket.Close();
  console.log('WebSocket窗口关闭事件触发');
};

// 浏览器刷新重新连接
// 刷新页面后需要重连-并且是在登录之后
try {
  const navigationEntries = performance.getEntriesByType('navigation') as PerformanceNavigationTiming[];
  if (navigationEntries.length > 0 && navigationEntries[0].type === 'reload') {
    console.log('WebSocket检测到浏览器刷新，启动永久连接');

    // 延迟一定时间再执行 WebSocket 初始化，确保页面完全加载后再进行连接
    setTimeout(() => {
      console.log('WebSocket执行刷新后永久重连...');
      // 刷新后重连
      const username = JSON.parse(localStorage.getItem('msgprofile') || '{}')?.wx_id;
      if (username) {
        websocket.enableKeepAlive(); // 启用永久保持
        websocket.Init(username);
      }
    }, 500); // 增加延迟时间，确保页面完全加载
  }
} catch (error) {
  console.log('WebSocket检测刷新状态失败:', error);
}

// 暴露对象
